package com.okilo.online.app.fmt

import android.annotation.SuppressLint
import android.graphics.Typeface
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.okilo.online.app.R
import com.okilo.online.app.act.OkiloProcessStepsAct
import com.okilo.online.app.common.OkiloComFmt
import com.okilo.online.app.configs.OkiloConfigs.addParams
import com.okilo.online.app.databinding.OkiloFmtStepGeneralBinding
import com.okilo.online.app.event.OkiloEventData
import com.okilo.online.app.event.OkiloEventPointType
import com.okilo.online.app.event.room.OkiloPointManager
import com.okilo.online.app.tools.OkiloAssetsFileReader
import com.okilo.online.app.tools.OkiloDensityUtil
import com.okilo.online.app.tools.decoration.LinearSpacingItemDecoration
import com.okilo.online.app.tools.extensions.toJSONObjectList
import com.okilo.online.app.tools.extensions.toListWithModification
import com.okilo.online.app.tools.log.OkiloLog
import com.okilo.online.app.apt.OkiloStepGeneralApt
import com.okilo.online.app.dialog.OkiloSelectPopup
import com.okilo.online.app.weight.font.OkiloRbtSemiBoldButton
import com.okilo.online.app.weight.pickerview.builder.TimePickerBuilder
import com.okilo.online.app.weight.pickerview.listener.OnTimeSelectListener
import com.okilo.online.app.weight.pickerview.view.TimePickerView
import org.json.JSONArray
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date

/**
 * OkiloLoan
 * @Author wwdeng
 * @CreateTime: 2024/11/19 14:19
 * @Annotation：认证流程 - 通用
 */
class OkiloStepGeneralFmt(): OkiloComFmt() {
    private var _binding: OkiloFmtStepGeneralBinding? = null
    private var stepItem: JSONObject? = null

    private var generalAdapter: OkiloStepGeneralApt? = null
    private var selectPosition = -1

    //出生日期选择
    private var pvStartDateView: TimePickerView? = null
    var startTime = 0L

    //个人信息中 需要从 assets 文件中读取的城市数据
    var cityList: ArrayList<JSONObject>? = null

    override var pageName: String = ""

    constructor(data: JSONObject): this(){
        this.stepItem = data
        pageName = "${data.optString("stepTitle")}_Page"
    }

    override fun createOkiloContentView(inflater: LayoutInflater): View? {
        _binding = OkiloFmtStepGeneralBinding.inflate(inflater)
        return _binding?.root
    }

    override fun initializeOkiloViews() {
        getTitleBarManager().setRootBackgroundColor(getColor(R.color.okilo_color_transparent))
        initOkiloProcessStepListView()
    }

    override fun setupOkiloEventListeners() {
    }

    override fun loadOkiloData() {
        if (pageName == "personal_info"){
            val showKey = getString(R.string.okilo_process_step_personal_info_data_security_key)
            val showText = String.format(getString(R.string.okilo_process_step_personal_info_data_security),showKey)
            val startIndex = showText.indexOf(showKey)
            val dataSecuritySpannable = SpannableString(showText)
            dataSecuritySpannable.setSpan(ForegroundColorSpan(getColor(R.color.okilo_color_ff0084a2)), startIndex, startIndex + showKey.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            //加粗
            dataSecuritySpannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + showKey.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            _binding?.textPersonalInfoDataSecurity?.text = dataSecuritySpannable
            _binding?.dataSecurityLayout?.visibility = View.VISIBLE
        } else {
            _binding?.dataSecurityLayout?.visibility = View.GONE
        }

        stepItem?.let {
            _binding?.okiloProcessStepTitle?.text = it.optString("showTitle")
            val dataList = it
                .optJSONArray("dataList")
                ?.toListWithModification { item ->
                    item.put("stepTitle", pageName)
                } ?: emptyList()
            generalAdapter?.data = dataList
        }
    }

    /**
     * 初始化Views
     */
    private fun initOkiloProcessStepListView(){
        _binding?.okiloProcessStepGeneralListView?.setHasFixedSize(false)
        _binding?.okiloProcessStepGeneralListView?.isNestedScrollingEnabled = false
        _binding?.okiloProcessStepGeneralListView?.isFocusableInTouchMode = false //不需要焦点
        val layoutManager = LinearLayoutManager(context)
        layoutManager.orientation = RecyclerView.VERTICAL
        _binding?.okiloProcessStepGeneralListView?.layoutManager = layoutManager
        val topDecoration = OkiloDensityUtil.dp2px(14f)
        _binding?.okiloProcessStepGeneralListView?.addItemDecoration(
            LinearSpacingItemDecoration(
                0,
                0,
                0,
                topDecoration
            )
        )
        generalAdapter = OkiloStepGeneralApt(_binding?.okiloProcessStepGeneralListView)
        _binding?.okiloProcessStepGeneralListView?.adapter = generalAdapter
        _binding?.okiloProcessStepGeneralListView?.itemAnimator = DefaultItemAnimator()
        generalAdapter?.setOnItemChildClickListener { _, childView, position ->
            _binding?.root?.clearFocus()
            selectPosition = position
            generalAdapter?.let { adapter ->
                val item = adapter.getItem(position)
                when (item.optString("action")) {
                    "DATE_PICK" -> {//出生日期选择
                        sOkiloProcessStepBirthChooseDialog()
                    }
                    "SELECT" -> {//选择
                        val dataList = item.optJSONArray("values")?.toJSONObjectList() ?: emptyList()
                        sOkiloGeneralSelectItemPopup(childView, ArrayList(dataList))
                    }
                    "PICK_AREA" -> {//区域
                        if (cityList == null){
                            cityList = OkiloAssetsFileReader.readCityListFromAssets().apply {
                                forEach { it.apply {
                                    put("title", optString("name"))
                                    put("value", optString("name"))
                                }}
                            }
                        }
                        cityList?.let { sOkiloGeneralSelectItemPopup(childView, it) }
                    }
                    "PICK_STATE" -> {//状态 -> 需要从paramName=livingStreetArea中取 selectItem
                        handleStateSelection(adapter,childView)
                    }
                    "PICK_CITY" -> {//城市 -> 需要从paramName=livingStreetState中取 selectItem
                        handleCitySelection(adapter, childView)
                    }
                }
            }
        }
    }

    // 处理州/省选择
    private fun handleStateSelection(adapter: OkiloStepGeneralApt, childView: View) {
        val areaItem = adapter.data.findByParamName("livingStreetArea")
        val areaSelectItem = areaItem?.optJSONObject("selectItem") ?: run {
            showOkiloToast("${areaItem?.getFormattedHint()}")
            return
        }

        val dataList = areaSelectItem.optJSONArray("children")?.toNameValueList() ?: emptyList()
        sOkiloGeneralSelectItemPopup(childView, ArrayList(dataList))
    }

    // 处理城市选择
    private fun handleCitySelection(adapter: OkiloStepGeneralApt, childView: View) {
        val stateItem = adapter.data.findByParamName("livingStreetState")
        val stateSelectItem = stateItem?.optJSONObject("selectItem") ?: run {
            showOkiloToast("${stateItem?.getFormattedHint()}")
            return
        }

        val dataList = stateSelectItem.optJSONArray("children")?.toStringValueList() ?: emptyList()
        sOkiloGeneralSelectItemPopup(childView, ArrayList(dataList))
    }

    //查找指定 paramName 的项
    private fun List<JSONObject>.findByParamName(paramName: String): JSONObject? {
        return find { it.optString("paramName") == paramName }
    }

    //格式化提示信息
    private fun JSONObject.getFormattedHint(): String {
        return "${optString("hint")}${optString("title").replace("*", "")}"
    }

    // 将 children 数组转换为 name-value 列表
    private fun JSONArray.toNameValueList(): List<JSONObject> {
        return List(length()) { index ->
            optJSONObject(index).apply {
                put("title", optString("name"))
                put("value", optString("name"))
            }
        }
    }

    // 将字符串数组转换为 title-value 列表
    private fun JSONArray.toStringValueList(): List<JSONObject> {
        return List(length()) { index ->
            JSONObject().apply {
                put("title", this@toStringValueList.optString(index))
                put("value", this@toStringValueList.optString(index))
            }
        }
    }

    /**
     * 选择选项
     */
    private fun sOkiloGeneralSelectItemPopup(view: View, dataList: ArrayList<JSONObject>){
        val selectPopup = OkiloSelectPopup(requireContext())
        selectPopup.setWindowWidth(view.width + OkiloDensityUtil.dp2px(10f))
        selectPopup.setSelectItemListener(object : OkiloSelectPopup.IItemClickListener {
            //完成
            override fun onConfirmAction(data: JSONObject?) {
                generalAdapter?.let { adapter ->
                    val item = adapter.getItem(selectPosition)
                    val currentSelectItem = item.optJSONObject("selectItem")
                    // 选择和上次一样的内容，不处理
                    if (currentSelectItem?.optString("value") == data?.optString("value")) {
                        return@let
                    }
                    item.put("selectItem",data)
                    adapter.notifyItemChanged(selectPosition)

                    if (data != null){
                        val subRemark = "${data.optString("value")}$$${data.optString("duration")}"
                        addEventPointRequestAction(String.Companion.format(OkiloEventPointType.OKILO_CLICK_TRACK.STEP_XX_SELECT,"${item.optString("stepTitle")}_${item.optString("paramName")}"),subRemark)
                    }
                    //判断特殊逻辑
                    val paramName = item.optString("paramName")
                    when (paramName) {
                        "livingStreetArea" -> {//选择的是 paramName="livingStreetArea" 时，需要置空 livingStreetState、livingStreetCity
                            clearSelectItems(adapter, "livingStreetState", "livingStreetCity")
                        }
                        "livingStreetState" -> {//当选择的是 paramName="livingStreetState" 时，需要置空 livingStreetCity
                            clearSelectItems(adapter, "livingStreetCity")
                        }
                    }
                }
            }
            //关闭监听
            override fun onDismissListener() {
            }
        })
        _binding?.let {
            selectPopup.show(view, it.root)
            selectPopup.setBrandList(dataList)
        }
    }

    // 清除选择项
    private fun clearSelectItems(adapter: OkiloStepGeneralApt, vararg paramNames: String) {
        paramNames.forEach { paramName ->
            val index = adapter.data.indexOfFirst { it.optString("paramName") == paramName }
            if (index != -1) {
                adapter.data[index].put("selectItem", null)
                adapter.notifyItemChanged(index)
            }
        }
    }

    /**
     * 生日选择dialog
     */
    private fun sOkiloProcessStepBirthChooseDialog(){
        //开始选择时间
        startTime = System.currentTimeMillis()
        if(pvStartDateView == null){
            //时间可选范围18-100岁
            //当前日期
            val curtDate = Calendar.getInstance()
            val startDate = Calendar.getInstance()
            startDate.timeInMillis = curtDate.timeInMillis
            startDate.add(Calendar.YEAR,-100)

            val endDate = Calendar.getInstance()
            endDate.timeInMillis = curtDate.timeInMillis
            endDate.add(Calendar.YEAR,-18)

            pvStartDateView = TimePickerBuilder(requireContext(), object : OnTimeSelectListener {
                override fun onTimeSelect(date: Date?, v: View?) {
                }

                @SuppressLint("SimpleDateFormat")
                override fun onTimeSelectString(date: Date?, showDate: String?) {
                    val value = SimpleDateFormat("yyyy-MM-dd").format(date)
                    //可根据需要自行截取数据显示
                    val item = generalAdapter?.getItem(selectPosition)
                    item?.let {
                        val obj = JSONObject()
                        obj.put("title", showDate)
                        obj.put("title_sw", showDate)
                        obj.put("value", value)
                        it.put("selectItem", obj)

                        generalAdapter?.notifyItemChanged(selectPosition)

                        val subRemark = "${value}$$${System.currentTimeMillis() - startTime}"
                        addEventPointRequestAction(
                            String.Companion.format(
                                OkiloEventPointType.OKILO_CLICK_TRACK.STEP_XX_SELECT,
                                "${item.optString("stepTitle")}_${item.optString("paramName")}"
                            ), subRemark
                        )
                    }
                }
            })
                .setDate(endDate) //默认选中
                .setRangDate(startDate, endDate) //可选择时间范围
                .setLayoutRes(R.layout.okilo_dlog_birthdate) { v ->
                    val ivClose = v.findViewById<ImageView>(R.id.okiloBirthCloseIcon)
                    ivClose.setOnClickListener {
                        pvStartDateView?.dismiss()
                    }
                    //确定
                    val btnConfirm = v.findViewById<OkiloRbtSemiBoldButton>(R.id.okiloBirthButtonConfirm)
                    btnConfirm.setOnClickListener {
                        pvStartDateView?.returnData()
                        pvStartDateView?.dismiss()
                    }
                }
                .isDialog(true)
                .setContentTextSize(16)
                .setType(booleanArrayOf(true, true, true, false, false, false))
                .setLabel("", "", "", "", "", "")
                .setLineSpacingMultiplier(3.5f)
                .setTextXOffset(65, 65, 65, 65, 65, 65)
                .isCenterLabel(false)//是否只显示中间选中项的label文字，false则每项item全部都带有label。
                .setTextColorCenter(getColor(R.color.okilo_color_ff0c092a)) //设置选中项文字颜色
                .setTextColorOut(getColor(R.color.okilo_color_ffc8c8c8))//默认颜色
                .setBgColor(getColor(R.color.okilo_color_transparent))
                .isAlphaGradient(true)
                .setItemVisibleCount(3)
                .isCyclic(true)
                .setDividerColor(ContextCompat.getColor(requireContext(), R.color.okilo_color_transparent))
                .build()
            val dialog = pvStartDateView?.dialog
            dialog?.let {
                val dialogWindow = it.window
                if (dialogWindow != null) {
                    val params = dialogWindow.attributes
                    params.width = WindowManager.LayoutParams.MATCH_PARENT
                    params.height = WindowManager.LayoutParams.WRAP_CONTENT
                    dialogWindow.attributes = params
                    dialogWindow.setWindowAnimations(R.style.dialog_slide_anim) //修改动画样式
                    dialogWindow.setGravity(Gravity.CENTER)
                    dialogWindow.setDimAmount(0.3f)
                }
            }
        }
        pvStartDateView?.show()
    }

    /**
     * 通用类型列表
     * 检查是否填写完整
     * 当且仅当 isMust=”NO“为非必填
     */
    private fun isAllowCommonSubmit(): Boolean{
        //是否允许提交
        return generalAdapter?.let { adapter ->
            adapter.data.all { item ->
                // 非必填项直接跳过
                if (item.has("isMust") && item.optString("isMust") == "NO") {
                    return@all true
                }

                // 检查必填项是否有有效内容
                val selectItem = item.optJSONObject("selectItem")
                selectItem != null && selectItem.optString("value").isNotEmpty()
            }
        } ?: false
    }

    /**
     * 提交
     */
    private fun subOkiloProcessStepGeneralInfo(){
        _binding?.root?.clearFocus()
        val currentStepItem = stepItem ?: return

        if (!isAllowCommonSubmit()){
            showErrorTipsDialog(getString(R.string.okilo_dlog_tips_submit_error), pageName)
            return
        }
        val params = JSONObject().addParams().apply {
            put("path",currentStepItem.optString("apiUrl").replace("/",""))

            // 收集所有有效的 selectItem 数据
            generalAdapter?.data?.forEach { item ->
                item.optJSONObject("selectItem")?.let { selectItem ->
                    put(item.optString("paramName"), selectItem.optString("value"))
                }
            }
        }

        addEventPointRequestAction(String.Companion.format(OkiloEventPointType.OKILO_CLICK_TRACK.STEP_XX_NEXT, pageName),"")
        // TODO: 进件信息点下一步 需上报所有埋点
        OkiloPointManager.getInstance().manualReport()

        OkiloLog.i(">>>>>>submit data >>>>>>>$params")
        val act = getAct() as OkiloProcessStepsAct
        act.sOkiloProcessStepSubmitAction(params)
    }

    override fun onOkiloPublishEvent(event: OkiloEventData) {
        super.onOkiloPublishEvent(event)
        when(event.eventType){
            OkiloEventData.TYPE.OKILO_PROCESS_STEP_SUBMIT -> {
                subOkiloProcessStepGeneralInfo()
            }
            else -> {

            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}